#pragma once

#include "Log.hpp"
#include "Err.hpp"
#include <stdlib.h>
#include <string>
#include <sys/epoll.h>
#include <string.h>

namespace zxf
{
    class Epoll
    {

    public:
        Epoll() : _epfd(-1)
        {
        }
        ~Epoll()
        {
            Close()
        }

        void Create()
        {
            _epfd = epoll_create(1);
            // 这个参数在大多数情况下被忽略，可以设置为任意值（建议大于 0）
            //  如果调用失败，它将返回 -1，并设置相应的错误码，可以通过全局变量 errno 获取具体的错误信息。
            if (_epfd == -1)
            {
                logMessage(FATAL, "epoll_create err , errno: %d, strerror: %s", errno, strerror(errno));
                exit(EPOLL_CREATE);
            }
        }

        void Control(int op, int fd, int ev)
        {
            struct epoll_event event;
            event.data.fd = fd;
            event.events = ev;
            int ret = epoll_ctl(_epfd, op, fd, &event);
            if (ret == 0)
            {
                logMessage(NORMAL, "epoll_ctl success, add_df: %d", fd);
            }
            else if (ret == -1)
            {
                logMessage(FATAL, "epoll_ctl err, add_df: %d", fd);
                exit(EPOLL_CTL);
            }
            else
            {
                logMessage(FATAL, "epoll_ctl err,  unknown error");
                exit(EPOLL_CTL);
            }
        }
        int Wait(struct epoll_event *events, int num, int timeout)
        {
            int ret = epoll_wait(_epfd, events, num, timeout);
            if (ret == -1)
            {
                logMessage(WARNING, "epoll_wait failed, code: %d, errstring: %s", errno, strerror(errno));
                return -1;
            }
            else if (ret == 0)
            {
                logMessage(NORMAL, "timeout!!!");
                return -1;
            }
            else
            {
                // 有事件就绪
                logMessage(NORMAL, " hare event ready !! ");
                return ret;
            }
        }

        void Close()
        {
            if (_epfd > 0)
            {
                close(_epfd);
            }
        }

    private:
        int _epfd = -1;
    };
}